package z_mxsTest.testCleanMutiLangCommonWithList;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 多语言代码注释批量清理工具
 * 
 * 【核心功能】
 * 1. 支持按规则批量匹配多种编程语言文件（Java/C/C#/C++/JS等）
 * 2. 精准清理两种类型注释：
 *    - 单行注释：/ / 开头至行尾的内容（如 // 这是单行注释）
 *    - 多行注释：/ * 开头至 * \/ 结尾的内容（支持跨多行，如 / * 多行注释 换行仍有效 * \ /）
 * 3. 提供可视化界面，支持规则预览、文件匹配预览和清理日志追踪
 * 
 * 【使用步骤】
 * 1. 准备工作：
 *    - 在代码根目录创建规则文件 targetlist.txt（文件名固定）
 *    - 按规则格式编写需要处理的文件路径规则（参考下方"规则文件格式"）
 * 
 * 2. 运行工具：
 *    - 启动本程序（运行main方法），打开可视化界面
 *    - 点击"浏览目录"，选择包含 targetlist.txt 的代码根目录
 *    - 系统自动加载规则并显示匹配到的文件列表
 *    - 确认列表无误后，点击"开始清理注释"（建议先备份文件）
 *    - 通过底部日志区查看清理进度和结果
 * 
 * 【规则文件格式（targetlist.txt）】
 * - 每行一条匹配规则，空行和 # 开头的行视为注释（会被忽略）
 * - 支持通配符：
 *   *   ：匹配单层目录中的任意字符（如 src/*.java 匹配src下所有.java文件）
 *   **  ：匹配任意多级目录（如 src/ * * /*.cs 匹配src及子目录下所有.cs文件）
 *   ?   ：匹配单个字符（如 test/file?.txt 匹配file1.txt、file2.txt等）
 * - 路径分隔符支持 / 或 \（自动适配Windows和Linux系统）
 * 
 *   示例内容：
 *   # 这是注释行（会被忽略）
 *   src/main/java/** /*.java    # 匹配src/main/java及子目录下所有.java文件
 *   src/test/cpp/*.h           # 匹配src/test/cpp下所有.h头文件
 *   docs/example?.js           # 匹配docs下example1.js、exampleA.js等文件
 * 
 * 【文件目录结构要求】
 * 代码根目录
 * ├── targetlist.txt          # 规则文件（必须存在）
 * ├── src/                    # 待处理代码目录（示例）
 * │   ├── main/
 * │   │   └── java/...
 * │   └── test/...
 * └── other-files/...         # 其他待处理文件或目录
 * 
 * 【注意事项】
 * 1. 操作前请备份文件：工具会直接覆盖原文件，无法撤销
 * 2. 编码支持：默认使用UTF-8编码读写文件，如需其他编码（如GBK），可修改代码中StandardCharsets.UTF_8
 * 3. 权限问题：无读写权限的文件会清理失败，日志区会显示具体错误信息
 * 4. 特殊情况：字符串中的//或/*不会被误清理（如 "http://example.com" 保持原样）
 */

public class CommentCleanerApplication extends JFrame {
    private static final long serialVersionUID = 1L;

    // GUI组件
    private JTextField rootDirInput;
    private JTextArea ruleDisplayArea;
    private JTextArea fileDisplayArea;
    private JTextArea logDisplayArea;

    // 数据存储
    private File selectedRootDir;
    private List<String> loadedRules = new ArrayList<>();
    private List<File> matchedFiles = new ArrayList<>();

    // 功能模块
    private final RuleLoader ruleLoader;
    private final FileMatcher fileMatcher;
    private final CommentCleaner commentCleaner;
    private final LogUtils logUtils;

    public CommentCleanerApplication() {
        this.logUtils = new LogUtils(this);
        this.ruleLoader = new RuleLoader(this, logUtils);
        this.fileMatcher = new FileMatcher(this, logUtils);
        this.commentCleaner = new CommentCleaner(this, logUtils);
        initUI();
        setVisible(true);
    }

    private void initUI() {
        setTitle("多语言注释清理工具");
        setSize(1050, 750);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setLayout(new BorderLayout(15, 15));

        Container contentPane = getContentPane();
        if (contentPane instanceof JComponent) {
            ((JComponent) contentPane).setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
        }

        add(createRootDirPanel(), BorderLayout.NORTH);
        add(createRuleAndFilePanel(), BorderLayout.CENTER);
        add(createLogAndButtonPanel(), BorderLayout.SOUTH);
    }

    private JPanel createRootDirPanel() {
        JPanel panel = new JPanel(new BorderLayout(10, 10));
        JLabel label = new JLabel("代码根目录（含targetlist.txt）：");
        rootDirInput = new JTextField();
        rootDirInput.setEditable(false);
        JButton browseBtn = new JButton("浏览目录");

        browseBtn.addActionListener(e -> {
            JFileChooser chooser = new JFileChooser();
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int result = chooser.showOpenDialog(this);
            if (result == JFileChooser.APPROVE_OPTION) {
                selectedRootDir = chooser.getSelectedFile();
                rootDirInput.setText(selectedRootDir.getAbsolutePath());
                ruleLoader.loadRules(selectedRootDir, loadedRules, ruleDisplayArea);
                fileMatcher.matchFiles(selectedRootDir, loadedRules, matchedFiles, fileDisplayArea);
            }
        });

        panel.add(label, BorderLayout.WEST);
        panel.add(rootDirInput, BorderLayout.CENTER);
        panel.add(browseBtn, BorderLayout.EAST);
        return panel;
    }

    private JPanel createRuleAndFilePanel() {
        JPanel panel = new JPanel(new GridLayout(1, 2, 10, 10));

        // 规则显示面板
        JPanel rulePanel = new JPanel(new BorderLayout(10, 10));
        rulePanel.add(new JLabel("匹配规则（来自targetlist.txt）："), BorderLayout.NORTH);
        ruleDisplayArea = new JTextArea();
        ruleDisplayArea.setEditable(false);
        rulePanel.add(new JScrollPane(ruleDisplayArea), BorderLayout.CENTER);

        // 文件列表面板
        JPanel filePanel = new JPanel(new BorderLayout(10, 10));
        filePanel.add(new JLabel("匹配到的目标文件："), BorderLayout.NORTH);
        fileDisplayArea = new JTextArea();
        fileDisplayArea.setEditable(false);
        filePanel.add(new JScrollPane(fileDisplayArea), BorderLayout.CENTER);

        panel.add(rulePanel);
        panel.add(filePanel);
        return panel;
    }

    private JPanel createLogAndButtonPanel() {
        JPanel panel = new JPanel(new BorderLayout(10, 10));

        // 日志面板
        JPanel logPanel = new JPanel(new BorderLayout(10, 10));
        logPanel.add(new JLabel("处理日志："), BorderLayout.NORTH);
        logDisplayArea = new JTextArea();
        logDisplayArea.setEditable(false);
        logPanel.add(new JScrollPane(logDisplayArea), BorderLayout.CENTER);

        // 按钮面板
        JPanel btnPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
        JButton refreshBtn = new JButton("刷新规则与文件");
        JButton cleanBtn = new JButton("开始清理注释");
        JButton clearLogBtn = new JButton("清空日志");

        refreshBtn.addActionListener(e -> {
            if (selectedRootDir != null) {
                ruleLoader.loadRules(selectedRootDir, loadedRules, ruleDisplayArea);
                fileMatcher.matchFiles(selectedRootDir, loadedRules, matchedFiles, fileDisplayArea);
                logUtils.log("已刷新规则与文件列表");
            }
        });

        cleanBtn.addActionListener(e -> {
            if (checkCleanReady()) {
                int confirm = JOptionPane.showConfirmDialog(
                        this,
                        "确认清理" + matchedFiles.size() + "个文件？\n⚠️ 直接覆盖原文件，请先备份！",
                        "确认清理",
                        JOptionPane.YES_NO_OPTION,
                        JOptionPane.WARNING_MESSAGE
                );
                if (confirm == JOptionPane.YES_OPTION) {
                    new Thread(() -> commentCleaner.cleanFiles(matchedFiles, selectedRootDir)).start();
                }
            }
        });

        clearLogBtn.addActionListener(e -> {
            logDisplayArea.setText("");
            logUtils.log("日志已清空");
        });

        btnPanel.add(refreshBtn);
        btnPanel.add(cleanBtn);
        btnPanel.add(clearLogBtn);

        panel.add(logPanel, BorderLayout.CENTER);
        panel.add(btnPanel, BorderLayout.SOUTH);
        return panel;
    }

    private boolean checkCleanReady() {
        if (selectedRootDir == null || !selectedRootDir.exists()) {
            JOptionPane.showMessageDialog(this, "请选择有效根目录", "错误", JOptionPane.ERROR_MESSAGE);
            return false;
        }
        if (loadedRules.isEmpty()) {
            JOptionPane.showMessageDialog(this, "未加载到有效规则", "错误", JOptionPane.ERROR_MESSAGE);
            return false;
        }
        if (matchedFiles.isEmpty()) {
            JOptionPane.showMessageDialog(this, "未匹配到目标文件", "提示", JOptionPane.INFORMATION_MESSAGE);
            return false;
        }
        return true;
    }

    public JTextArea getLogDisplayArea() {
        return logDisplayArea;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(CommentCleanerApplication::new);
    }
}